#ifndef MYOBJECTASINTRUSIVEPTR_H
#define MYOBJECTASINTRUSIVEPTR_H

///////////////////////////////////////////////////////////////////////////////
//
// MyObjectAsIntrusivePtr.h
//
///////////////////////////////////////////////////////////////////////////////
//
// Author:            Jan Maes
// Created:           Sunday, June 15, 2008
// Responsibilities:  Objects of class MyObjectAsIntrusivePtr can only be
//                    created using the HandleFactory::HandleFactory::Create
//                    member functions. As a result we get a
//                    boost::intrusive_ptr<MyObjectAsIntrusivePtr> object as 
//                    output.
//
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// Includes
///////////////////////////////////////////////////////////////////////////////

#include <HandleFactory/HandleFactory.h>

#include <boost/smart_ptr.hpp>

///////////////////////////////////////////////////////////////////////////////
// MyObjectAsIntrusivePtr
///////////////////////////////////////////////////////////////////////////////

class MyObjectAsIntrusivePtr : public HandleFactory::HandleFactory<MyObjectAsIntrusivePtr, boost::intrusive_ptr<MyObjectAsIntrusivePtr>, true>
  {
  private:
    friend class HandleFactory::HandleFactory<MyObjectAsIntrusivePtr, boost::intrusive_ptr<MyObjectAsIntrusivePtr>, true>;

    MyObjectAsIntrusivePtr() : m_double(0.0), m_counter(0)
      {
      }

    explicit MyObjectAsIntrusivePtr(double i_double) : m_counter(0)
      {
      m_double = i_double;
      }

  public:

    ~MyObjectAsIntrusivePtr()
      {
      }
  
    double GetDouble() const 
      {
      return m_double;
      }

    size_t GetRefCount()
      {
      return m_counter;
      }

    void RefIncrement()
      {
      ++m_counter;
      }

    void RefDecrement()
      {
      --m_counter;
      }

  private:

    double m_double;
    size_t m_counter;

  };

///////////////////////////////////////////////////////////////////////////////

void intrusive_ptr_add_ref(MyObjectAsIntrusivePtr* ip_my_instrusive_ptr_object)
  {
  ip_my_instrusive_ptr_object->RefIncrement();
  }

///////////////////////////////////////////////////////////////////////////////

void intrusive_ptr_release(MyObjectAsIntrusivePtr* ip_my_instrusive_ptr_object)
  {
  ip_my_instrusive_ptr_object->RefDecrement();
  if (ip_my_instrusive_ptr_object->GetRefCount() == 0)
      delete ip_my_instrusive_ptr_object;
  }

///////////////////////////////////////////////////////////////////////////////

#endif